home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_3b.arc / PWCOMMON.ARC / TTYCLS.C < prev    next >
C/C++ Source or Header  |  1989-02-14  |  9KB  |  362 lines

  1. /*
  2.  * TTYCLS module
  3.  *
  4.  * Written by Bill Hall
  5.  * 3665  Benton Street, #66
  6.  * Santa Clara, CA 95051
  7.  *
  8.  * This file supports a teletype style window in either Microsoft
  9.  * windows or Presentation Manager.
  10.  *
  11.  * For an example of its use, see the source code for WINAUX
  12.  * or PMAUX.
  13.  *
  14.  * If being used in a Windows program, be sure to define WINDOWS
  15.  */
  16.  
  17. #ifdef WINDOWS
  18. #define NOCOMM        /* stops a bunch of unneeded level 3 warnings */
  19. #define NOKANJI
  20. #define NOATOMS
  21. #define NOMINMAX
  22. #include <windows.h>
  23. #else
  24. #define INCL_PM
  25. #include <os2.h>
  26. extern HAB hAB;        /* these should be defined in the main program */
  27. extern HHEAP hHeap;
  28. extern FATTRS ttyfat;
  29. #endif
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <memory.h>
  33. #include "ascii.h"
  34. #include "ttycls.h"
  35.  
  36. /* local functions */
  37. static void NEAR DoLF(PTTYWND pTTYWnd);
  38. static void NEAR DoCR(PTTYWND pTTYWnd);
  39. static void NEAR DoBS(PTTYWND pTTYWnd);
  40. static void NEAR DoTab(PTTYWND pTTYWnd);
  41.  
  42. void NEAR TTYClear(PTTYWND pTTYWnd)
  43. {
  44.     memset(pTTYWnd->pVidBuf, NUL, pTTYWnd->MaxLines * pTTYWnd->MaxLineLength);
  45.     DoCR(pTTYWnd);
  46. #ifdef WINDOWS
  47.     InvalidateRect(pTTYWnd->hWnd, (LPRECT)NULL, TRUE);
  48.     UpdateWindow(pTTYWnd->hWnd);
  49. #else
  50.     WinInvalidateRect(pTTYWnd->hWnd, (PRECTL)NULL, TRUE);
  51.     WinUpdateWindow(pTTYWnd->hWnd);    
  52. #endif
  53. }
  54.  
  55. /* 
  56.  * Called at create window time.  Creates a text buffer based
  57.  * on the passed in width, height, and the character width and height.
  58.  * Other parameters such as wrap, character mask, etc. are also set.
  59.  */
  60. InitTTYWindow(pTTYWnd,left,top,width,height,charwidth,charheight,LFonCR,CRonLF,
  61.                 wrap, fontindex, mask)
  62. PTTYWND pTTYWnd;
  63. short left, top, width, height, charwidth, charheight;
  64. BOOL LFonCR, CRonLF, wrap;
  65. short fontindex;
  66. BYTE mask; 
  67. {
  68.     
  69.     int bufsize;
  70.  
  71.     pTTYWnd->Left = left;
  72.     pTTYWnd->Top = top;
  73.     pTTYWnd->Width = width;
  74.     pTTYWnd->Height = height;
  75.     pTTYWnd->CWidth = charwidth;
  76.     pTTYWnd->CHeight = charheight;
  77.     pTTYWnd->MaxLines = height / charheight;
  78.     pTTYWnd->MaxCols = width / charwidth;
  79.     pTTYWnd->MaxLineLength = pTTYWnd->MaxCols + 1;
  80.     bufsize = pTTYWnd->MaxLines * pTTYWnd->MaxLineLength;
  81.  
  82.   /* allocate space for the display characters */
  83.   /* if allocation successful, initialize the remaining tty data */
  84.  
  85. #ifdef WINDOWS
  86.     if (pTTYWnd->hVidBuf = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, bufsize)) {
  87.     pTTYWnd->pVidBuf = LocalLock(pTTYWnd->hVidBuf); /* lock the buffer */
  88.         pTTYWnd->Pos.y = (pTTYWnd->MaxLines - 1) * charheight - 1;
  89. #else
  90.     if (pTTYWnd->pVidBuf = WinAllocMem(hHeap, bufsize)) {
  91.     memset(pTTYWnd->pVidBuf, NUL, bufsize);
  92.         pTTYWnd->Pos.y = 1;
  93. #endif
  94.         pTTYWnd->Pos.x = 0;
  95.     pTTYWnd->oCurrentLine = pTTYWnd->CurLineOffset = 0;
  96.     pTTYWnd->oVidLastLine = (pTTYWnd->MaxLines-1) * pTTYWnd->MaxLineLength;
  97.     pTTYWnd->LFonCR = LFonCR;
  98.     pTTYWnd->CRonLF = CRonLF;
  99.         pTTYWnd->Wrap = wrap;
  100.     pTTYWnd->FontIndex = fontindex;
  101.     pTTYWnd->ebitmask = mask;
  102.       return TRUE;
  103.     }
  104.     return FALSE;
  105. }
  106.  
  107. /* display the characters contained in str */
  108. int NEAR TTYDisplay(PTTYWND pTTYWnd, short len, BYTE *str)
  109. {
  110.  
  111.     HPS hPS;
  112.     register BYTE *ptr;
  113.     register short ctr;
  114.     short toff, txpos;
  115.     BYTE *tbuf;
  116.     short findex = pTTYWnd->FontIndex;
  117.     short cols = pTTYWnd->MaxCols;
  118.     short cwidth = pTTYWnd->CWidth;
  119.     BYTE mask = pTTYWnd->ebitmask;
  120.     
  121.     while (len) {
  122.        ptr = str;
  123.     ctr = 0;
  124.      txpos = (short)pTTYWnd->Pos.x;
  125.      tbuf = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  126.     toff = pTTYWnd->CurLineOffset;
  127.  
  128.     while((*ptr &= mask) >= SP) {
  129.         if ((len) && (toff < cols)) {
  130.         ctr += 1;
  131.         *(tbuf + toff++) = *ptr++;
  132.         txpos += cwidth;
  133.         len -= 1;
  134.         }
  135.         else
  136.         break;
  137.     }
  138.     if (ctr) {
  139. #ifdef WINDOWS
  140.         hPS = GetDC(pTTYWnd->hWnd);
  141.         SetBkColor(hPS, GetSysColor(COLOR_WINDOW));
  142.         SetTextColor(hPS, GetSysColor(COLOR_WINDOWTEXT));
  143.         if (findex != SYSTEM_FONT)
  144.             SelectObject(hPS, GetStockObject(findex));
  145.         TextOut(hPS, pTTYWnd->Pos.x, pTTYWnd->Pos.y, (LPSTR)str, ctr);
  146.         ReleaseDC(pTTYWnd->hWnd, hPS);
  147. #else
  148.         hPS = WinGetPS(pTTYWnd->hWnd);
  149.         if (findex) {
  150.                 GpiCreateLogFont(hPS, (PSTR8)"TTYCLS",(LONG)findex, &ttyfat);
  151.             GpiSetCharSet(hPS,(LONG)findex);
  152.         }
  153.         GpiSetBackMix(hPS, BM_OVERPAINT);
  154.         GpiCharStringAt(hPS,(PPOINTL)&pTTYWnd->Pos,(LONG)ctr,(PCH)str);
  155.         GpiRestorePS(hPS, -1L);
  156.         WinReleasePS (hPS);
  157. #endif
  158.         if (toff < cols) {
  159.             pTTYWnd->CurLineOffset = toff;
  160. #ifdef WINDOWS
  161.             pTTYWnd->Pos.x = txpos;
  162. #else
  163.             pTTYWnd->Pos.x = (LONG)txpos;
  164. #endif
  165.         }
  166.         else
  167.         if (pTTYWnd->Wrap) {
  168.             DoCR(pTTYWnd);
  169.             DoLF(pTTYWnd);
  170.             }        
  171.     }
  172.     while ((*ptr &= mask) < SP) {
  173.         if (len) {
  174.         switch(*ptr) {
  175.             case BEL:
  176. #ifdef WINDOWS
  177.             MessageBeep(0);
  178. #else
  179.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  180. #endif
  181.             break;
  182.             case HT:
  183.             DoTab(pTTYWnd);
  184.             break;            
  185.             case CR:
  186.             DoCR(pTTYWnd);
  187.             if (pTTYWnd->LFonCR)
  188.                 DoLF(pTTYWnd);
  189.             break;
  190.             case LF:
  191.             if (pTTYWnd->CRonLF)
  192.                 DoCR(pTTYWnd);
  193.             DoLF(pTTYWnd);
  194.             break;
  195.             case BS:
  196.             DoBS(pTTYWnd);
  197.             break;
  198.         }
  199.         len -= 1;
  200.         ptr++;
  201.         }
  202.         else
  203.         break;
  204.     }
  205.         str = ptr;
  206.     }
  207.     return (len);
  208. }
  209.  
  210. /* perform a carriage return */
  211. static void NEAR DoCR(PTTYWND pTTYWnd)
  212. {
  213.     pTTYWnd->CurLineOffset = 0;
  214.     pTTYWnd->Pos.x = 0;
  215. }
  216.  
  217. /* perform a line feed */
  218. static void NEAR DoLF(PTTYWND pTTYWnd)
  219. {
  220.     BYTE *pCurr;
  221.     short offset, cols;
  222.     int i;
  223.     HWND hWnd = pTTYWnd->hWnd;
  224.     cols = pTTYWnd->MaxCols;
  225.  
  226.     if ((pTTYWnd->oCurrentLine+=pTTYWnd->MaxLineLength) > pTTYWnd->oVidLastLine)
  227.     pTTYWnd->oCurrentLine = 0;
  228.     pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  229.     offset = pTTYWnd->CurLineOffset;
  230.  
  231.     for (i = 0; i < offset; i++)
  232.     *(pCurr + i) = SP;
  233.     for (i = offset; i < cols; i++)
  234.     *(pCurr + i) = NUL;
  235.  
  236. #ifdef WINDOWS
  237.     ScrollWindow(hWnd,0,-pTTYWnd->CHeight,(LPRECT)NULL,(LPRECT)NULL);
  238.     UpdateWindow(hWnd);
  239. #else
  240.     WinScrollWindow(hWnd,0,pTTYWnd->CHeight,
  241.                 NULL,NULL,NULL,NULL,SW_INVALIDATERGN);
  242.     WinUpdateWindow(hWnd);    
  243. #endif
  244. }
  245.  
  246. /* perform a backspace */
  247. static void NEAR DoBS(PTTYWND pTTYWnd)
  248. {
  249.     if (pTTYWnd->CurLineOffset > 0) {
  250. #ifdef WINDOWS
  251.     pTTYWnd->Pos.x -= pTTYWnd->CWidth;
  252. #else
  253.     pTTYWnd->Pos.x -= (LONG)pTTYWnd->CWidth;
  254. #endif
  255.     pTTYWnd->CurLineOffset -= 1;
  256.     }
  257. }
  258.  
  259. /* Horizontal tab */
  260. static void NEAR DoTab(pTTYWnd)
  261. PTTYWND pTTYWnd;
  262. {
  263.  
  264.     short curoffset, xpos, ypos, cols, cwidth;
  265.     BYTE *pCurr;
  266. #ifdef WINDOWS
  267.     RECT myrect;
  268. #else
  269.     RECTL myrect;
  270. #endif
  271.     cols = pTTYWnd->MaxCols;
  272.     curoffset = pTTYWnd->CurLineOffset;
  273.     cwidth = pTTYWnd->CWidth;
  274.  
  275.     if (curoffset < (cols - 1)) {
  276.         xpos = (short)pTTYWnd->Pos.x;        /* initialize variables */
  277.         ypos = (short)pTTYWnd->Pos.y;
  278.         pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  279.         do {
  280.         if (*(pCurr + curoffset) == NUL)  /* if null, replace with space */
  281.             *(pCurr + curoffset) = SP;
  282.         curoffset += 1;        /* update offsets */
  283.         xpos += cwidth;
  284.         } while ((curoffset % 8 != 0) && (curoffset < (cols - 1)));
  285.  
  286.     /* now invalidate the part of the screen affected */
  287. #ifdef WINDOWS
  288.     SetRect((LPRECT)&myrect, xpos, ypos, pTTYWnd->Width, pTTYWnd->Height);
  289.     InvalidateRect(pTTYWnd->hWnd, (LPRECT)&myrect, TRUE);
  290. #else
  291.     WinSetRect(hAB,&myrect,xpos,ypos,pTTYWnd->Width,ypos+pTTYWnd->CHeight);
  292.     WinInvalidateRect(pTTYWnd->hWnd, &myrect, TRUE);
  293. #endif
  294.     /* finally, reset the tty window variables */
  295.         pTTYWnd->Pos.x = xpos;
  296.         pTTYWnd->CurLineOffset = curoffset;
  297.     }
  298. }
  299.  
  300. /* repaint the window */
  301. void NEAR TTYWndPaint(PTTYWND pTTYWnd, HPS hPS, short top, short bottom)
  302. {
  303.  
  304. #ifdef WINDOWS
  305.     POINT pt;
  306.     short wtop;
  307. #else
  308.     POINTL pt;
  309. #endif
  310.     BYTE *lineptr;
  311.     BYTE *pBuf, *pEnd;
  312.     short lines, length;
  313.     short cheight;
  314.     short findex;
  315.     int i;
  316.  
  317.     findex = pTTYWnd->FontIndex;
  318.     pt.x = 0;
  319.     pBuf = pTTYWnd->pVidBuf;
  320.     pEnd = pBuf + pTTYWnd->oVidLastLine;
  321.  
  322.     lineptr = pBuf + pTTYWnd->oCurrentLine;
  323.     pt.y = pTTYWnd->Pos.y;
  324.  
  325.     length = pTTYWnd->MaxLineLength;
  326.     cheight = pTTYWnd->CHeight;
  327. #ifdef WINDOWS
  328.     wtop = pTTYWnd->Height - top;
  329.     lines = wtop / cheight;
  330.     if (wtop % cheight)
  331.     lines += 1;
  332.     lines = min(pTTYWnd->MaxLines, lines);
  333.     SetBkColor(hPS, GetSysColor(COLOR_WINDOW));
  334.     SetTextColor(hPS, GetSysColor(COLOR_WINDOWTEXT));
  335.     if (findex != SYSTEM_FONT)
  336.         SelectObject(hPS, GetStockObject(findex));
  337. #else
  338.     lines = top / cheight;
  339.     if (top % cheight)
  340.     lines += 1;
  341.     lines = min(pTTYWnd->MaxLines, lines);
  342.     GpiErase (hPS);
  343.     GpiSetBackMix(hPS, BM_OVERPAINT);
  344.     if (findex = pTTYWnd->FontIndex) {
  345.         GpiCreateLogFont(hPS, (PSTR8)"TTYCLS",(LONG)findex, &ttyfat);
  346.         GpiSetCharSet(hPS,(LONG)findex);
  347.     }
  348. #endif
  349.  
  350.     for (i = 0; i < lines; i++) {
  351. #ifdef WINDOWS
  352.         TextOut(hPS, pt.x, pt.y, (LPSTR)lineptr, strlen(lineptr));
  353.     pt.y -= cheight;
  354. #else
  355.         GpiCharStringAt(hPS,&pt,(LONG)strlen(lineptr),(PCH)lineptr);
  356.     pt.y += (LONG)cheight;
  357. #endif
  358.         if ((lineptr -= length) < pBuf)
  359.         lineptr = pEnd;
  360.     }
  361. }
  362.